#ifndef TABOOEXPIRE_H_
#define TABOOEXPIRE_H_

#include "edgeID.h"
#include <stdbool.h>

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~DEFINIZIONI~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/**rappresenta la data di espirazione di un singolo Taboo.Il meccanismo di taboo prevede 2 elementi: un contatore incrementale (clock) che viene
 * incrementato ad ogni iterazione dell'algoritmo e una matrice implementante la Taboo List. tale matrice ha come elemento
 * base la struttura Taboo. Il programma, per comprendere se un arco e' taboo oppure no effettua un confronto tra il valore del clock
 * attuale, il valore di tenure e il timeStamp secondo la regola:
 * <p><i>is taboo if time_current <= edge.timestamp+edge+tenure;</i></p>
 * Questo a livello fisico viene implementato secondo una specie di "cookie": il TabooDataExpiration e' fondamentalmente
 * una data di espirazione di un dato taboo, ossia un valore del clock. Se il valore attuale del clock e' maggiore
 * della data di espirazione il dato e' considerato obsoleto.
 * Tale struttura indica il numero dell'iterazione a cui è prevista la scadenza dell'appartenenza dell'arco alla Taboo List
 */
typedef unsigned long TabooExpire;
/**Utile se si vogliono gestire dei taboo tramite passaggio per riferimento. */
typedef TabooExpire* PtabooExpire;

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~COSTRUTTORI/DISTRUTTORI~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/**costruisce un nuovo taboo
 * @param _tenure indica la tenure del nuovo taboo
 * @param now l'iterazione corrente dell'algoritmo, cioè quella di creazione.
 * @return un puntatore alla variabile TabooDataExpiration
 */
PtabooExpire initTabooExpire(int _tenure, TabooExpire now);

/**libera la memoria da questo taboo
 * @param taboo il taboo da deallocare
 */
void freeTabooExpire(PtabooExpire taboo);

/**verifica se questo oggetto e' ancora sotto taboo oppure no
 *
 * @param taboo il taboo da verificare
 * @param now l'iterazione corrente dell'algoritmo
 * @return TRUE se taboo>=now, FALSE altrimenti
 */
bool isTaboo(PtabooExpire taboo, TabooExpire now);

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~STAMPA~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/**stampa in modo leggibile il taboo specificato. Il comportamento della funzione e' imprevedibile qualora il taboo
 * passato sia NULL
 *
 * @param f il file su cui stampare il taboo
 * @param taboo il taboo da stampare
 */
void printTabooExpire(FILE* f, PtabooExpire taboo);

/** questo metodo dovrebbe essere usato solo dalle procedure di stampa; la business logic dovrebbe interrogare solo isTaboo().
 *  se un giorno nascessere criteri di aspirazione basati su 'quanta tenure manchi a un edge', avrebbe senso che la logica
 *  interrogasse getTenure().
 *
 * @param f il file su cui stampare
 * @param taboo il taboo da confrontare
 * @param now l'iterazione corrente dell'algoritmo
 * @return la differenza tra l'iterazione di scadenza del taboo e quella corrente, ovvero il TENURE TIME.
 *	qualora la differenza sia negativa, la clippa a zero.
 */
int getTenure(PtabooExpire t, TabooExpire now);

#endif /* TABOOEXPIRE_H_ */
